
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;

namespace HyuFrameWork
{
    public class ResService : ServiceBase
    {
        private static ABService _abService;
        private static ABService AbService => _abService ??= ServiceManager.Check<ABService>();

        #region 加载Battle外的资源

        private Dictionary<string, GameObject> prefabDic = new Dictionary<string, GameObject>();
        
        public GameObject LoadPrefab(string abName,string resName, bool cache = true) 
        {
            if(!prefabDic.TryGetValue(resName, out var prefab)) 
            {
                prefab = AbService.LoadRes<GameObject>(abName,resName);
                if(cache) 
                    prefabDic.Add(resName, prefab);
            }
            
            if (prefab != null)
            {
                GameObject go = Instantiate(prefab);
                return go;
            }
            return null;
        }
        
        public GameObject LoadPrefab(string abName,string resName, Transform parent,bool cache = true) 
        {
            if(!prefabDic.TryGetValue(resName, out var prefab)) 
            {
                prefab = AbService.LoadRes<GameObject>(abName,resName);
                if(cache) 
                    prefabDic.Add(resName, prefab);
            }
            
            if (prefab != null)
            {
                GameObject go = Instantiate(prefab,parent);
                return go;
            }
            return null;
        }

        public GameObject LoadPrefab(string abName,string resName,
            Vector3 pos,Quaternion ro,Transform parent,bool cache = true) 
        {
            if(!prefabDic.TryGetValue(resName, out var prefab)) 
            {
                prefab = AbService.LoadRes<GameObject>(abName,resName);
                if(cache) 
                    prefabDic.Add(resName, prefab);
            }
            
            if (prefab != null)
            {
                GameObject go = Instantiate(prefab,pos,ro,parent);
                return go;
            }
            return null;
        }        

        #endregion

        #region 加载Battle资源

        private Dictionary<string, GameObject> battlePrefabDic = new Dictionary<string, GameObject>();
        public GameObject LoadBattlePrefab(string resName, bool cache = true) 
        {
            if(!battlePrefabDic.TryGetValue(resName, out var prefab)) 
            {
#if UNITY_EDITOR
                if (GlobalVariables.Instance.ResourceLoad)
                    prefab = Resources.Load<GameObject>(resName+" Variant");
                if(prefab == null)
                    prefab = AbService.LoadRes<GameObject>("battle",resName);
#else
                prefab = AbService.LoadRes<GameObject>("battle",resName);
#endif
                if (cache)
                {
                    battlePrefabDic.Add(resName, prefab);
                }
            }
            
            if (prefab != null)
            {
                GameObject go = Instantiate(prefab);
                return go;
            }
            return null;
        }
        
        public GameObject LoadBattlePrefab(string resName, Transform parent,bool cache = true) 
        {
            if(!battlePrefabDic.TryGetValue(resName, out var prefab)) 
            {
#if UNITY_EDITOR
                if (GlobalVariables.Instance.ResourceLoad)
                    prefab = Resources.Load<GameObject>(resName+" Variant");
                if(prefab == null)
                    prefab = AbService.LoadRes<GameObject>("battle",resName);
#else
                prefab = AbService.LoadRes<GameObject>("battle",resName);
#endif
                if(cache) 
                    battlePrefabDic.Add(resName, prefab);
            }
            
            if (prefab != null)
            {
                GameObject go = Instantiate(prefab,parent);
                return go;
            }
            return null;
        }

        public GameObject LoadBattlePrefab(string resName,
            Vector3 pos,Quaternion ro,Transform parent,bool cache = true) 
        {
            if(!battlePrefabDic.TryGetValue(resName, out var prefab)) 
            {
#if UNITY_EDITOR
                if (GlobalVariables.Instance.ResourceLoad)
                    prefab = Resources.Load<GameObject>(resName+" Variant");
                if(prefab == null)
                    prefab = AbService.LoadRes<GameObject>("battle",resName);
#else
                prefab = AbService.LoadRes<GameObject>("battle",resName);
#endif
                if(cache) 
                    battlePrefabDic.Add(resName, prefab);
            }
            
            if (prefab != null)
            {
                GameObject go = Instantiate(prefab,pos,ro,parent);
                return go;
            }
            return null;
        }
        
        private Dictionary<string, AudioClip> battleAudioDic = new Dictionary<string, AudioClip>();
        public AudioClip LoadBattleAudio(string resName, bool cache = true) 
        {
            if(!battleAudioDic.TryGetValue(resName, out var audio)) 
            {
                audio = AbService.LoadRes<AudioClip>("battle",resName);
                if(cache) {
                    battleAudioDic.Add(resName, audio);
                }
            }
            return audio;
        }

        public void CleanBattleRes()
        {
            battlePrefabDic.Clear();
            battleAudioDic.Clear();
        }
        #endregion

        #region 加载音频
        private Dictionary<string, AudioClip> audioDic = new Dictionary<string, AudioClip>();
        public AudioClip LoadAudio(string abName,string resName, bool cache = true) 
        {
            if(!audioDic.TryGetValue(resName, out var audio)) 
            {
                audio = AbService.LoadRes<AudioClip>(abName,resName);
                if(cache) {
                    audioDic.Add(resName, audio);
                }
            }
            return audio;
        }
        #endregion

        #region 加载图片

        private Dictionary<string, Sprite> spriteDic = new Dictionary<string, Sprite>();
        public Sprite LoadSprite(string abName,string resName, bool cache = true)
        {
            if(!spriteDic.TryGetValue(resName, out var sprite)) 
            {
                sprite = AbService.LoadRes<Sprite>(abName,resName);
                if(cache) 
                {
                    spriteDic.Add(resName, sprite);
                }
            }
            return sprite;
        }

        #endregion

        #region 加载场景

        public void AsyncLoadSceneByAb(string sceneName, UnityAction<float> abLoadRate,
            UnityAction<float> sceneLoadRate, UnityAction loaded)
        {
            AbService.LoadABAsync("map/"+sceneName, abLoadRate,
                sceneAsset =>
                {
                    StartCoroutine(ReallyAsyncLoadScene(sceneName,sceneLoadRate, loaded));
                });
        }

        IEnumerator ReallyAsyncLoadScene(string sceneName,UnityAction<float> sceneLoadRate, UnityAction loaded)
        {
            var sceneAsync = SceneManager.LoadSceneAsync(sceneName);
            if (sceneLoadRate != null)
            {
                while (true)
                {
                    var progress = sceneAsync.progress;
                    sceneLoadRate.Invoke(progress);
                    if (sceneAsync.isDone)
                    {
                        loaded?.Invoke();
                        break;
                    }
                    yield return null;
                }
            }
            else
            {
                yield return sceneAsync;
                loaded?.Invoke();
            }
        }

        #endregion
        
    }
}
